package main

import (
	"errors"
	"reflect"
)

//● 实现队列，先入先出
//● push方法（入一个），pop方法（出一个），top方法（返回队头元素），length方法（返回长度）
//● 切片的元素实例可以是任意类型，但同一个TSlice实例的元素只能是一个类型

//t.push()
//t.pop()
//t.top()
//t.length()

type TSlice struct {
	//inType用于标识类型
	iType interface{}
	//iVal用于存值
	iVal []interface{}
}

// InitTSlice 初始化这个tSlice
func InitTSlice(in ...interface{}) (*TSlice, error) {
	typeIn := reflect.TypeOf(in[0])
	tSlice := new(TSlice)
	tSlice.iType = in[0]
	for _, val := range in {
		if !reflect.TypeOf(val).AssignableTo(typeIn) {
			return nil, errors.New("接口类型不一样")
		}
		tSlice.iVal = append(tSlice.iVal, val)
	}
	return tSlice, nil
}

func (t *TSlice) Push(in interface{}) error {
	if !reflect.TypeOf(t.iType).AssignableTo(reflect.TypeOf(in)) {
		return errors.New("接口类型不一样")
	}
	t.iVal = append(t.iVal, in)
	return nil
}

func (t *TSlice) Pop() interface{} {
	if len(t.iVal) == 0 {
		panic("没有元素")
	}
	re := t.iVal[len(t.iVal)-1]
	t.iVal = t.iVal[:len(t.iVal)-1]
	return re
}

func (t *TSlice) Top() interface{} {
	if len(t.iVal) == 0 {
		panic("没有元素")
	}
	return t.iVal[0]
}

func (t *TSlice) Length() int {
	return len(t.iVal)
}
